Momentum in Equities - Jagadeesh and Titman (1993)
Momentum in Commodities - Well know to CTA practitioners.
Momentum in Fixed Income
Momentum in Currency Markets
Increased risk during market turning points & period of increase volatility
Observed heightened
Multiasset momentum strategy tends to work better than single asset momentum strategy due to diversification. However, this is not as effective when cross-asset correlations are high. Such was the case during 2010 - 2012 period.
Application of Lasso Regression to estimate 1-day returns of assets in a cross-asset momentum model.
Independent variables:
To calibrate the model, we used a rolling window of 500 trading days (~2y); re-calibration was performed once every 3 months.
The model was used to predict the next day’s return.
If the next day predicted return was positive, we went long the asset, otherwise we shorted it.
Prior to regression, all inputs were standardized to avoid the problem of input features being of different scales.
In [1]:
import pandas as pd
import numpy as np
In [2]:
from sklearn import linear_model
In [3]:
tickers = ['SPY', 'IEF', 'UUP', 'GLD']
data = get_pricing(symbols(tickers), start_date='2007-4-1', end_date='2009-8-1',
fields='close_price', frequency='daily')
data.columns = [ticker.symbol for ticker in data.columns]
data.index.name = 'Date'
In [4]:
data.tail()
Out[4]:
In [5]:
data[:-1].tail()
Out[5]:
In [6]:
res_1m = []
for e in data.columns:
res_1m.append(data[e].pct_change(20)[1:])
res_1m = pd.DataFrame(res_1m).T
res_1m.columns = [e + '_1m' for e in data.columns]
res_1m = res_1m.dropna()
In [7]:
res_3m = []
for e in data.columns:
res_3m.append(data[e].pct_change(60)[1:])
res_3m = pd.DataFrame(res_3m).T
res_3m.columns = [e + '_3m' for e in data.columns]
res_3m = res_3m.dropna()
In [8]:
res_6m = []
for e in data.columns:
res_6m.append(data[e].pct_change(120)[1:])
res_6m = pd.DataFrame(res_6m).T
res_6m.columns = [e + '_6m' for e in data.columns]
res_6m = res_6m.dropna()
In [9]:
res_12m = []
for e in data.columns:
res_12m.append(data[e].pct_change(240)[1:])
res_12m = pd.DataFrame(res_12m).T
res_12m.columns = [e + '_12m' for e in data.columns]
res_12m = res_12m.dropna()
In [10]:
res = res_1m.join(res_3m).join(res_6m).join(res_12m)
res = res.dropna()
res.head()
Out[10]:
In [11]:
y = data['SPY'].pct_change()[1:][len(data['SPY'].pct_change()) - len(res):]
y.head()
Out[11]:
In [12]:
len(y)
Out[12]:
In [13]:
y.head()
Out[13]:
In [14]:
y.tail()
Out[14]:
In [15]:
X = res.shift(1).dropna().copy()
X.head()
Out[15]:
In [16]:
len(X)
Out[16]:
In [17]:
test_start = '2009-01-01'
In [18]:
X_train = X[X.index < test_start]
X_test = X[X.index >= test_start]
y_train = y[y.index < test_start]
y_test = y[y.index >= test_start]
In [19]:
X_train.shape, y_train.shape
Out[19]:
In [20]:
X_test.shape, y_test.shape
Out[20]:
In [21]:
from sklearn.preprocessing import StandardScaler
sc_X = StandardScaler()
X_train = sc_X.fit_transform(X_train)
sc_y = StandardScaler()
y_train = sc_y.fit_transform(y_train)
In [22]:
reg = linear_model.Lasso(alpha = 0.001, normalize = True)
reg.fit(X_train, y_train)
Out[22]:
In [23]:
reg.coef_
Out[23]:
In [24]:
reg.intercept_
Out[24]:
In [33]:
regressor = linear_model.LinearRegression()
In [34]:
regressor.fit(X_train, y_train)
Out[34]:
In [35]:
regressor.coef_
Out[35]:
In [25]:
# Transform test data
X_test_trans = sc_X.transform(X_test)
In [26]:
# Predict!
y_pred = reg.predict(X_test_trans)
In [27]:
from sklearn.metrics import explained_variance_score, mean_absolute_error, mean_squared_error, r2_score
In [28]:
explained_variance_score(y_test, y_pred)
Out[28]:
In [29]:
mean_absolute_error(y_test, y_pred)
Out[29]:
In [30]:
mean_squared_error(y_test, y_pred)
Out[30]:
In [31]:
r2_score(y_test, y_pred)
Out[31]:
Linear Regression
In [36]:
bt = get_backtest('596cbed9a625dc549d3d6ab7')
In [37]:
bt.create_full_tear_sheet()
Lasso
In [38]:
bt = get_backtest('596cbf052493b4522b5156f6')
In [39]:
bt.create_full_tear_sheet()
In [ ]: